
import { __private, Component, _decorator, Node, Prefab, instantiate, PhysicsSystem, Vec3, UICoordinateTrackerComponent, EventHandler, EventTouch, SpriteComponent, Sprite, SpriteFrame, Camera, Label, v3, Mat4 } from "cc";
import { EventHandlers } from "../EventHandlers";
const { ccclass, property } = _decorator;

/**位置映射到UI节点,并自动更新该UI节点的位置*/
@ccclass('PositionMapToUIComponent')
export class PositionMapToUIComponent extends Component {

    @property({ type: Node, tooltip: "映射到哪个UI节点" })
    get targetUI() {
        return this._targetUI;
    }
    set targetUI(value) {
        if (this._targetUI === value) {
            return;
        }
        this._targetUI = value;
        this._checkCanMove();
    }

    @property({ type: Camera, tooltip: "使用的相机" })
    get camera() {
        return this._camera;
    }
    set camera(value) {
        if (this._camera === value) {
            return;
        }
        this._camera = value;
        this._checkCanMove();
    }

    @property({ tooltip: "是否缩放映射, 即根据相机和物体的距离比例缩放映射到UI" })
    get useScale() {
        return this._useScale;
    }
    set useScale(value) {
        if (this._useScale === value) {
            return;
        }
        this._useScale = value;
    }

    @property({ tooltip: "摄像机距离物体的距离多少为正常(映射到UI节点上的缩放为1)" })
    get distance() {
        return this._distance;
    }
    set distance(value) {
        if (this._distance === value) {
            return;
        }
        this._distance = value;
    }

    @property({ tooltip: "是否自动设置目标UI节点的position" })
    public autoMap: boolean = true;

    public syncEvents: EventHandlers<(pos: Vec3) => void> = new EventHandlers<() => void>(this);

    protected _targetUI: Node | null = null;
    protected _camera: Camera | null = null;
    protected _useScale = false;
    protected _distance = 1;

    protected _transformPos = new Vec3();
    protected _viewPos = new Vec3();
    protected _canMove = true;
    protected _lastWPos = new Vec3(-99999,-99999,-99999);
    protected _lastCameraPos = new Vec3(-99999,-99999,-99999);


    start() {
        this._checkCanMove();
    }
    onEnable() {
        this._checkCanMove();
    }
    protected _checkCanMove() {
        this._canMove = !!(this.camera && this.targetUI && this.targetUI.parent);
    }

    update() {
        const wPos = this.node.worldPosition;
        const camera = this.camera;
        if (!this._canMove || !camera || !camera.camera || (this._lastWPos.equals(wPos) && this._lastCameraPos.equals(camera.node.worldPosition))) {
            return;
        }
        this._lastWPos.set(wPos);
        this._lastCameraPos.set(camera.node.worldPosition);
        // [HACK]
        camera.camera.update();
        camera.convertToUINode(wPos, this.targetUI!.parent!, this._transformPos);

        if (this._useScale) {
            Vec3.transformMat4(this._viewPos, this.node.worldPosition, camera.camera.matView);
        }

        const data = this.distance / Math.abs(this._viewPos.z);

        if (this.autoMap) {
            this.targetUI?.setPosition(this._transformPos.x, this._transformPos.y, 0);
            if (this._useScale) {
                this.targetUI?.setScale(data, data, data);
            }
        }

        this.syncEvents.trigger(this._transformPos, data);

    }
}